/*
 * @Description:
 * @Version: 1.0
 * @Autor: ycb
 * @Date: 2022-03-22 08:42:25
 * @LastEditors: ycb
 * @LastEditTime: 2022-04-01 18:11:28
 */
package server

import (
	"TITAN-STREAM-PROXY/public/hex"
	rabiitmq "TITAN-STREAM-PROXY/public/rabbitmq"
	flv "TITAN-STREAM-PROXY/server/flv_client"
	"fmt"
	"log"
	"net"
	"net/http"
	"sync"
)

type FLV struct {
	RabbitConfig        RabbitMQConfig
	FLV_Port            string
	RabbitmqQueueConfig RabbitmqQueueConfig
	flv_head_map        map[string][]byte
	lock_flv_head       sync.Mutex
	lock_flv_client     sync.Mutex
	flv_client_map      map[string]*flv.FlvClient
}

// 解析序列化数据并将数据加入队列
func (flv_server *FLV) paserStream(stream_chan chan []byte) {
	for bytes := range stream_chan {
		// 取出数据进行解析
		//log.Printf("%s", bytes)
		var paser_index uint64 = 0
		_ = paser_index
		var flv_path_bytes []byte
		_ = flv_path_bytes
		var flv_bytes []byte
		_ = flv_bytes
		var flv_head_len uint64 = 0
		_ = flv_head_len
		var flv_head_bytes []byte
		_ = flv_head_bytes

		// 解析前8个字节
		for i := 0; i < 3; i++ {

			if (int)(paser_index+8) > len(bytes) {
				log.Printf("解析字节超长不合规")
				return
			}

			//先解析出长度
			length, sucess := hex.Hex2uint64(bytes[paser_index : paser_index+8])
			if !sucess {
				return
			}
			paser_index += 8
			if (int)(paser_index+length) > len(bytes) {
				log.Printf("解析字节超长不合规")
				return
			}
			bytes_ := bytes[paser_index : paser_index+length]
			paser_index += length

			switch i {
			case 0:
				{
					flv_head_bytes = bytes_
				}
				break
			case 1:
				{
					flv_path_bytes = bytes_
				}
				break

			case 2:
				{

					flv_bytes = bytes_
				}
				break
			}

		}

		flv_server.lock_flv_head.Lock()
		flv_server.flv_head_map[string(flv_path_bytes)] = flv_head_bytes
		flv_server.lock_flv_head.Unlock()

		flv_server.lock_flv_client.Lock()
		for flv_client_kyes, client := range flv_server.flv_client_map {
			if client.URL_PATH == string(flv_path_bytes) {
				if !client.SetFlvStream(flv_bytes) {
					delete(flv_server.flv_client_map, flv_client_kyes)
					// 删除完后携程退出
					client.Close()
					client.SocketWaitChan <- flv_client_kyes
				}
			}
		}
		flv_server.lock_flv_client.Unlock()

	}
}

func (flv_server *FLV) entry_flv(res http.ResponseWriter, req *http.Request) {
	log.Printf("http-flv 连接创建%s", req.RemoteAddr)
	// 支持跨域等
	res.Header().Add("Connection", "keep-alive")
	res.Header().Add("Access-Control-Allow-Origin", "*")

	flv_server.lock_flv_head.Lock()
	flv_head, ok := flv_server.flv_head_map[req.URL.Path]
	flv_server.lock_flv_head.Unlock()
	if !ok {
		res.WriteHeader(404)
		log.Printf("未找到路由 %s flv头  客户端地址:%s", req.URL.Path, req.RemoteAddr)
		return
	}

	_, err := res.Write(flv_head)
	if err != nil {
		return
	}

	flv_client := &flv.FlvClient{
		SocketWaitChan: make(chan string),
		HttpRes:        res,
		HttpFlush:      res.(http.Flusher),
		URL_PATH:       req.URL.Path,
		FlvDataChan:    make(chan []byte),
		Key:            req.RemoteAddr,
	}

	go flv_client.Start()
	//time.Sleep(100 * time.Millisecond)

	flv_server.lock_flv_client.Lock()
	flv_server.flv_client_map[req.RemoteAddr] = flv_client
	flv_server.lock_flv_client.Unlock()

	keys := <-flv_client.SocketWaitChan
	log.Printf("http-flv 连接断开%s", keys)
}

// func (flv_server *FLV) flv_send_timer(send_timer interface{}) {
// 	for {

// 		<-send_timer.(*time.Ticker).C
// 		{
// 			for i := 0; i < len(flv_server.socket_array); i++ {
// 				socket_client := flv_server.socket_array[i]
// 				flv_server.lock.Lock()
// 				flv_bytes, ok := flv_server.media_map[socket_client.URL_PATH]
// 				flv_server.lock.Unlock()
// 				// 如果存在数据
// 				if ok {
// 					if _, err := socket_client.HttpRes.Write(flv_bytes); err != nil {
// 						log.Printf("Error on response writer")
// 						socket_client.SocketChan <- 0
// 						flv_server.socket_array = append(flv_server.socket_array[:i], flv_server.socket_array[i+1:]...)
// 						i--
// 						continue
// 					}
// 					socket_client.HttpFlush.Flush()
// 				}

// 			}

// 			// 刷完一轮后清空map
// 			flv_server.lock.Lock()
// 			for key, _ := range flv_server.media_map {

// 				delete(flv_server.media_map, key)

// 			}
// 			flv_server.lock.Unlock()
// 		}

// 	}

// }

func (flv_server *FLV) Start() {
	flv_server.flv_head_map = make(map[string][]byte)
	flv_server.flv_client_map = make(map[string]*flv.FlvClient)

	// 开启发送定时器
	//send_timer := time.NewTicker(time.Millisecond * 300)
	//go flv_server.flv_send_timer(send_timer)
	// 创建一个chan去接收从消息队列里拿出来的二进制数据
	stream := make(chan []byte)
	go flv_server.paserStream(stream)

	// 创建消息队列收数据
	client := &rabiitmq.RabbitMQPublishSubscribeClient{
		User: flv_server.RabbitConfig.User,
		Pwd:  flv_server.RabbitConfig.Pwd,
		IP:   flv_server.RabbitConfig.IP,
		Port: flv_server.RabbitConfig.Port,
	}

	go func() {
		Port := flv_server.FLV_Port
		//IsHttp := true

		flvListen, err := net.Listen("tcp", Port)
		if err != nil {
			log.Fatal(err)
		}

		mux := http.NewServeMux()
		fmt.Println("FLV server listens at ", Port)

		mux.HandleFunc("/", flv_server.entry_flv)

		if err := http.Serve(flvListen, mux); err != nil {
			return
		}
	}()

	// 开到携程里去
	go client.RecvMsg(flv_server.RabbitmqQueueConfig.Exchange,
		flv_server.RabbitmqQueueConfig.QueueName, stream)

	// 阻塞
	select {}
}
